const fs = require("fs");
const axios = require("axios");
const csv = require("csv-parser");
const querystring = require("querystring");
const https = require("https");
const file_name = "模板.csv";
const FormData = require("form-data");
const { resolve } = require("path");

let sso_url = "http://portal-apm-sdgs-ews.yy.sdgs.com.cn/auth/api/v1/login";
let apm_url = "http://portal-apm-sdgs-ews.yy.sdgs.com.cn/api-apm";
let sc_url = "http://saascomposer-sdgs-ews.yy.sdgs.com.cn";
let sc_display_path = "displays/包钢工艺/包钢-布袋除尘.json";
let org_id = 3;
let username = "abcdefg.shen@advantech.com.cn";
let password = "abcdefg";
let param_file_name = "脚本参数.csv";
// --------------------------------------------- //
let IMAGE_RESOURCE = "";
let IMAGE_DEFAULT = "";

function readFileSyncWithStream(filePath) {
  return new Promise((resolve, reject) => {
    const chunks = [];

    // 创建可读流
    const readStream = fs.createReadStream(filePath, { encoding: "utf-8" });

    // 监听 'data' 事件
    readStream.on("data", (chunk) => {
      chunks.push(chunk);
    });

    // 监听 'end' 事件
    readStream.on("end", () => {
      resolve(chunks.join("")); // 返回完整的文件内容
    });

    // 监听 'error' 事件
    readStream.on("error", (err) => {
      reject(err); // 返回错误
    });
  });
}

async function getParam() {
  return new Promise((resolve, reject) => {
    fs.createReadStream(param_file_name, { encoding: "utf-8" })
      .pipe(csv({ separator: ",", headers: ["名称", "数值"] }))
      .on("data", (row) => {
        let param_name = row["名称"];
        let param_value = row["数值"];
        switch (param_name) {
          case "sso_url":
            sso_url = `${param_value}/v4.0/auth/native`;
            console.log("参数sso_url：", sso_url);
            break;
          case "apm_url":
            apm_url = `${param_value}/api-apm`;
            console.log("参数apm_url：", apm_url);
            break;
          case "sc_url":
            sc_url = param_value;
            console.log("参数sc_url：", sc_url);
            break;
          case "username":
            username = param_value;
            console.log("参数username：", username);
            break;
          case "password":
            password = param_value;
            console.log("参数password：", password);
            break;
          case "sc_display_path":
            sc_display_path = param_value;
            console.log("参数sc_display_path：", sc_display_path);
            break;
          case "org_id":
            org_id = param_value;
            console.log("参数org_id：", org_id);
            break;
        }
      })
      .on("end", () => {
        resolve(true);
      })
      .on("error", () => {
        reject(false);
      });
  });
}
async function getToken() {
  const headers = {
    "Content-Type": "application/json",
  };
  const reqBody = {
    username: username,
    password: password,
  };
  try {
    // const result = await axios.get("https://www.baidu.com");
    const result = await axios.post(sso_url, reqBody, {
      headers,
      httpsAgent: new https.Agent({ rejectUnauthorized: false }),
    });
    console.log("result:", result.data);

    // const token = result.data.accessToken;
    // return `Bearer ${token}`;
  } catch (error) {
    console.error("123123:", error);
  }
}

async function getDisplays(token, path, orgId) {
  const url = `${sc_url}/${path}?org_id=${orgId}`;
  const headers = {
    Authorization: token,
    "Content-Type": "application/json",
  };
  try {
    const response = await axios.get(url, {
      headers,
      httpsAgent: new https.Agent({ rejectUnauthorized: false }),
    });
    return response.data;
  } catch (error) {
    console.error("displays error:", error);
    return null;
  }
}

async function getSymbols(token, image, orgId) {
  const url = `${sc_url}/${image}?org_id=${orgId}`;

  const headersObj = {
    Authorization: token,
    "Content-Type": "application/json",
  };

  let symbolsData = null;

  try {
    const response = await axios.get(url, {
      headers: headersObj,
      timeout: 30000,
    });

    if (response.status === 200) {
      symbolsData = response.data; // 直接使用 `response.data`，axios 会自动解析 JSON
    }
  } catch (error) {
    console.error("symbols error:", error.message);
  }

  return symbolsData;
}

async function getNodeInfo(token, nodeId) {
  const url = `${apm_url}/api/v1/asset/node/byid?id=${nodeId}`;

  const headersObj = {
    Authorization: token,
    "Content-Type": "application/json",
  };

  let apmData = null;

  try {
    const response = await axios.get(url, {
      headers: headersObj,
      timeout: 30000,
    });

    if (response.status === 200) {
      apmData = response.data; // 直接使用 `response.data`，axios 会自动解析 JSON
    }
  } catch (error) {
    console.error("node error:");
    // console.error("node error:", error.message);
  }

  return apmData;
}
async function getSensorInfo(token, nodeId) {
  const url = `${apm_url}/api/v1/node/property/byid/list?nodeIds=${nodeId}&componentName=EdgeInput&queryType=self&sortKey=id&sortType=DESC&index=0&count=1000`;

  const headersObj = {
    Authorization: token,
    "Content-Type": "application/json",
  };

  let apmData = null;

  try {
    const response = await axios.get(url, {
      headers: headersObj,
      timeout: 30000,
    });

    if (response.status === 200) {
      apmData = response.data; // axios 会自动解析 JSON
    }
  } catch (error) {
    console.error("sensor error:");
    // console.error("sensor error:", error.message);
  }

  return apmData;
}
async function postDisplays(token, path, displaysData, orgId) {
  const url = `${sc_url}/upload`;

  const formData = new FormData();
  formData.append("path", path);
  formData.append("content", JSON.stringify(displaysData));
  formData.append("org_id", orgId);

  const headersObj = {
    Authorization: token,
    ...formData.getHeaders(), // 自动设置 multipart/form-data 的边界
  };

  let result = null;

  try {
    result = await axios.post(url, formData, {
      headers: headersObj,
      timeout: 30000,
    });

    if (result.status === 200) {
      const content = result.data; // axios 会自动解析 JSON
      return content.id; // 返回内容中的 ID
    } else {
      console.error("请求失败");
      // console.error(result.data); // 输出错误信息
    }
  } catch (error) {
    console.error("更新图纸失败:", error.message);
  }

  return null;
}
async function getNodePathByNodeId(token, nodeId) {
  let nodePath = "";

  // 获取节点信息
  let nodeInfo = await getNodeInfo(token, nodeId);

  // 获取到父节点的 Id
  while (nodeInfo && nodeInfo.parentId !== 0) {
    nodePath = "|" + nodeInfo.parentId + nodePath;
    nodeInfo = await getNodeInfo(token, nodeInfo.parentId);
  }

  nodePath = nodeInfo ? nodeInfo.name + nodePath : nodePath; // 在最后添加当前节点的名称

  return nodePath;
}
// 调用示例
// getNodeInfo('your_token', 'your_node_id').then(data => console.log(data));
async function main() {
  const ready = await getParam();
  console.log("isReady", ready);
  if (!ready) return;
  const token = await getToken(); // 获取token
  return;
  const templateJson = {};

  try {
    const displaysData = await getDisplays(token, sc_display_path, org_id);
    const bindNodes = displaysData.d;

    if (bindNodes && bindNodes.length > 0) {
      for (const bindNode of bindNodes) {
        // 找到图标类型的 SC data
        if (bindNode.c === "ht.Node" && bindNode.a !== null) {
          const template = bindNode.p.displayName;
          const symbolsImage = bindNode.p.image;

          const symbols = await getSymbols(token, symbolsImage, org_id);
          const attrArray = [];

          if (symbols) {
            for (const attr of symbols.dataBindings) {
              attrArray.push(attr.attr);
            }
          }

          const nodeId = bindNode.a.nodeID;

          if (nodeId && !templateJson[nodeId]) {
            const nodePath = await getNodePathByNodeId(token, nodeId);
            const sensors = [];
            const nodeProperty = await getSensorInfo(token, nodeId);

            if (nodeProperty.nodeProperty) {
              for (const sensor of nodeProperty.nodeProperty) {
                sensors.push({
                  name: sensor.name,
                  type: sensor.componentName,
                });
              }
            }

            const templateInfo = {
              path: nodePath,
              sensors: sensors,
            };
            // 保存模板信息
            templateJson[nodeId] = templateInfo;
          }

          // 修改绑定信息
          const dataBindings = {};
          const a = {};

          if (templateJson[nodeId] && attrArray.length > 0) {
            const path = templateJson[nodeId].path;
            const pathArr = path.split("|");
            const sensors = templateJson[nodeId].sensors;

            for (const sensor of sensors) {
              const sensorName = sensor.name;
              const sensorType = sensor.type;

              if (attrArray.includes(sensorName)) {
                const targets = [];
                const target = {
                  sourceType: "APM",
                  formatType: "timeseries",
                  scDataType: "value",
                  target: `~|1|${path}|[[${nodeId}]]|${sensorType}|${sensorType}${sensorName}|real|`,
                  dateRange: "~",
                  maxPoint: "1",
                  topo: pathArr[0],
                  root: pathArr[1],
                  sensor: sensorType,
                  profile: `${sensorType}->${sensorName}`,
                  dataType: "real",
                };

                // 绑定 node1, node2... 等各级node信息
                for (let index = 0; index < pathArr.length; index++) {
                  if (index > 1) {
                    const key = `node${index - 1}`;
                    target[key] = pathArr[index];
                  }
                }

                target[`node${pathArr.length - 1}`] = `[[${nodeId}]]`;
                targets.push(target);

                // 绑定好的数据放到 a 中
                a[sensorName] = {
                  id: `${Math.floor(Date.now())}_0`,
                  animatedOptions: {
                    advancedAnimate: false,
                    func: "__ht__function(value, oldValue, option){ return value; }",
                    details: {
                      directFeed: true,
                      matchList: [],
                    },
                    animateCondition: "setMatch",
                    directFeed: true,
                  },
                  targets: targets,
                };
              }
            }

            // 绑定好的数据放到 dataBindings 中
            dataBindings.a = a;
            bindNode.p.dataBindings = dataBindings;
          }
        }
      }

      // 保存绑定好的图纸
      await postDisplays(token, sc_display_path, displaysData, org_id);
    }
  } catch (err) {
    console.error("error:", err);
  }

  console.log("finished");
}

main(); // 开始执行
